<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Ogl</title>
</head>
<body>
  <canvas width="512" height="512"></canvas>
  <script type="module">
    import {Renderer, Camera, Transform, Program, Geometry, Mesh, Orbit, Texture} from '../common/lib/ogl/index.mjs';
    import * as dat from '../common/lib/dat.gui.js';

    const canvas = document.querySelector('canvas');
    const renderer = new Renderer({
      canvas,
      width: 512,
      height: 512,
    });

    const gl = renderer.gl;
    gl.clearColor(1, 1, 1, 1);
    const camera = new Camera(gl, {fov: 35});
    camera.position.set(0, 0, 10);
    camera.lookAt([0, 0, 0]);

    const scene = new Transform();

    const vertex = /* glsl */ `
      precision highp float;

      attribute vec3 position;
      attribute vec3 normal;
      attribute vec2 uv;

      uniform mat4 modelViewMatrix;
      uniform mat4 projectionMatrix;

      varying vec2 vUv;

      void main() {
        vUv = uv;
        gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
      }
    `;

    const fragment = /* glsl */ `
      precision highp float;

      uniform sampler2D tMap;
      varying vec2 vUv;

      void main() {
        gl_FragColor = texture2D(tMap, vUv);
      }
    `;

    async function loadModel(src) {
      const data = await (await fetch(src)).json();

      const geometry = new Geometry(gl, {
        position: {size: 3, data: new Float32Array(data.position)},
        uv: {size: 2, data: new Float32Array(data.uv)},
        normal: {size: 3, data: new Float32Array(data.normal)},
      });

      return geometry;
    }

    function loadTexture(src) {
      const texture = new Texture(gl);
      return new Promise((resolve) => {
        const img = new Image();
        img.onload = () => {
          texture.image = img;
          resolve(texture);
        };
        img.src = src;
      });
    }

    (async function () {
      const geometry = await loadModel('../assets/airplane.json');
      const texture = await loadTexture('../assets/airplane.jpg');

      const program = new Program(gl, {
        vertex,
        fragment,
        uniforms: {
          tMap: {value: texture},
        },
      });
      const mesh = new Mesh(gl, {geometry, program});
      mesh.setParent(scene);
      renderer.render({scene, camera});

      const gui = new dat.GUI();
      const palette = {
        alpha: 0,
        beta: 0,
        theta: 0,
      };
      gui.add(palette, 'alpha', -180, 180).onChange((val) => {
        mesh.rotation.y = val / 180 * Math.PI;
        renderer.render({scene, camera});
      });
      gui.add(palette, 'beta', -180, 180).onChange((val) => {
        mesh.rotation.x = val / 180 * Math.PI;
        renderer.render({scene, camera});
      });
      gui.add(palette, 'theta', -180, 180).onChange((val) => {
        mesh.rotation.z = val / 180 * Math.PI;
        renderer.render({scene, camera});
      });
    }());
  </script>
</body>
</html>